--
--gcc -E head -o cpp.out


local function struct_end(code,offset)
    local _end = 0;
    while(true)do
        local ansi = code:sub(offset,offset);
        if(ansi=='{')then
            _end = _end + 1;
        elseif(ansi=='}')then
            _end = _end - 1;
        elseif(ansi==';')then
            if(_end<=0)then
                break;
            end
        end
        offset = offset+1;
    end
    return offset;
end

local function struct_begin(code,offset)
    local ret = offset;
    while(true and offset>=1)do
        local ansi = code:sub(offset,offset);
        if(ansi==';' or ansi=='}')then
            break;
        elseif(ansi=='\n' or ansi=='\t' or ansi=='\r')then
            
        else
            ret = offset;
        end
        offset = offset-1;
    end
    return ret;
end

local function FindStructOffsets(code)
    local offset = 0;
    local list = {};
    while(true)do
        local off = code:find('[%s]typedef[%s]',offset);
        local off2 = code:find('[%s]struct[%s]',offset);
        if(off==nil or (off2==nil) or off>off2)then off = off2; end;
        if(off==nil)then break; end;
        local _end = struct_end(code,off);
        local _begin = struct_begin(code,off);
        table.insert(list,{begin=_begin,_end=_end});
        offset = _end+1;
        --print(_end,offset,code:sub(offset-10,offset));
    end
    return list;
end
local out = io.stdout;
local function process(code)
    local list = FindStructOffsets(code);
    for k,v in ipairs(list)do
        --out:write('@'..k,code:sub(v.begin,v._end),'\n');
        out:write(code:sub(v.begin,v._end),'\n');
    end
end
if(arg[2])then
    out = io.open(arg[2],'w+');
end
local file = io.tmpfile();
for line in io.lines(arg[1])do
    if(line:find('#'))then
    else
        file:write(line,'\n');
    end
end
file:seek('set');
process(file:read('*a'));
